Skip to content

fixed duplicate present-proof v2 webhook#3998

Merged
jamshale merged 14 commits intoopenwallet-foundation:mainfrom
sonivijayk:sonivijayk/fix/issue-3802-presentation-xchg-webhook-dedup
Feb 23, 2026
Merged

fixed duplicate present-proof v2 webhook#3998
jamshale merged 14 commits intoopenwallet-foundation:mainfrom
sonivijayk:sonivijayk/fix/issue-3802-presentation-xchg-webhook-dedup

Conversation

@sonivijayk
Copy link
Contributor

Fix Summary

  1. Used by_format presence to drop legacy pres_* fields from webhook
  2. Added test for by_format logic based legacy fields exclusion from payload, used dummy payload

Fix Testing

  • Ran : python -m pytest acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py

@sonivijayk sonivijayk force-pushed the sonivijayk/fix/issue-3802-presentation-xchg-webhook-dedup branch from c7b95f1 to 33a7849 Compare January 3, 2026 19:46
@jamshale
Copy link
Contributor

jamshale commented Jan 6, 2026

I think this is looking good. My only reservation is that it would be considered a breaking change and I'm hesitant to include it in the next release.

I'll review it closer and we can probably get it included in the next, next release.

Also the DCO will need to get fixed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a webhook duplication issue (BUG #3802) where present-proof v2 webhooks included both legacy pres_* fields and the newer by_format structure, causing duplicate data in webhook payloads.

Key Changes:

  • Modified webhook emission logic to conditionally exclude legacy fields when by_format is present in debug mode
  • Extracted and centralized _presentation_request_payload helper function to handle both by_format and legacy payload formats
  • Added comprehensive test coverage for the webhook payload stripping behavior

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
acapy_agent/protocols/present_proof/v2_0/models/pres_exchange.py Added conditional logic to strip legacy pres_* fields from webhook payloads when by_format is present and debug webhooks are enabled
acapy_agent/protocols/present_proof/v2_0/models/tests/test_record.py Added test case to verify legacy fields are excluded from webhook payloads when by_format exists
scenarios/examples/util.py Added _presentation_request_payload helper function and new indy_present_proof_v2 function; updated anoncreds_presentation_summary and anoncreds_present_proof_v2 to use the helper
scenarios/examples/simple_restart/example.py Updated import to use indy_present_proof_v2 from util module
scenarios/examples/multitenancy/example.py Updated import to use indy_present_proof_v2 from util module
scenarios/examples/presenting_revoked_credential/example.py Added local _presentation_request_payload function and updated summary function to use it; updated import for indy_present_proof_v2
scenarios/examples/kanon_issuance_and_presentation/example.py Added local _presentation_request_payload function and updated summary function to use it
scenarios/examples/did_indy_issuance_and_revocation/example.py Added local _presentation_request_payload function and updated summary function to use it; updated import for indy_present_proof_v2

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 24 to 42
from examples.util import indy_present_proof_v2

ALICE = getenv("ALICE", "http://alice:3001")
BOB = getenv("BOB", "http://bob:3001")


def _presentation_request_payload(presentation: V20PresExRecord):
if presentation.by_format and presentation.by_format.pres_request:
return presentation.by_format.pres_request
request = presentation.pres_request
if not request:
return None
if isinstance(request, dict):
return request
if hasattr(request, "model_dump"):
return request.model_dump(by_alias=True)
return request.dict(by_alias=True)


Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function _presentation_request_payload is duplicated in this file. It already exists in scenarios/examples/util.py (lines 63-75) with identical implementation. Consider removing this duplicate and importing it from util.py instead to maintain DRY principles and reduce maintenance burden.

Suggested change
from examples.util import indy_present_proof_v2
ALICE = getenv("ALICE", "http://alice:3001")
BOB = getenv("BOB", "http://bob:3001")
def _presentation_request_payload(presentation: V20PresExRecord):
if presentation.by_format and presentation.by_format.pres_request:
return presentation.by_format.pres_request
request = presentation.pres_request
if not request:
return None
if isinstance(request, dict):
return request
if hasattr(request, "model_dump"):
return request.model_dump(by_alias=True)
return request.dict(by_alias=True)
from examples.util import indy_present_proof_v2, _presentation_request_payload
ALICE = getenv("ALICE", "http://alice:3001")
BOB = getenv("BOB", "http://bob:3001")

Copilot uses AI. Check for mistakes.
Comment on lines 32 to 42
def _presentation_request_payload(presentation: V20PresExRecord):
if presentation.by_format and presentation.by_format.pres_request:
return presentation.by_format.pres_request
request = presentation.pres_request
if not request:
return None
if isinstance(request, dict):
return request
if hasattr(request, "model_dump"):
return request.model_dump(by_alias=True)
return request.dict(by_alias=True)
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function _presentation_request_payload is duplicated in this file. It already exists in scenarios/examples/util.py (lines 63-75) with identical implementation. Consider removing this duplicate and importing it from util.py instead to maintain DRY principles and reduce maintenance burden.

Copilot uses AI. Check for mistakes.
Comment on lines 24 to 42
from examples.util import indy_present_proof_v2

ALICE = getenv("ALICE", "http://alice:3001")
BOB = getenv("BOB", "http://bob:3001")


def _presentation_request_payload(presentation: V20PresExRecord):
if presentation.by_format and presentation.by_format.pres_request:
return presentation.by_format.pres_request
request = presentation.pres_request
if not request:
return None
if isinstance(request, dict):
return request
if hasattr(request, "model_dump"):
return request.model_dump(by_alias=True)
return request.dict(by_alias=True)


Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function _presentation_request_payload is duplicated in this file. It already exists in scenarios/examples/util.py (lines 63-75) with identical implementation. Consider removing this duplicate and importing it from util.py instead to maintain DRY principles and reduce maintenance burden.

Suggested change
from examples.util import indy_present_proof_v2
ALICE = getenv("ALICE", "http://alice:3001")
BOB = getenv("BOB", "http://bob:3001")
def _presentation_request_payload(presentation: V20PresExRecord):
if presentation.by_format and presentation.by_format.pres_request:
return presentation.by_format.pres_request
request = presentation.pres_request
if not request:
return None
if isinstance(request, dict):
return request
if hasattr(request, "model_dump"):
return request.model_dump(by_alias=True)
return request.dict(by_alias=True)
from examples.util import indy_present_proof_v2, _presentation_request_payload
ALICE = getenv("ALICE", "http://alice:3001")
BOB = getenv("BOB", "http://bob:3001")

Copilot uses AI. Check for mistakes.
# anoncreds utilities:
def _presentation_request_payload(
presentation: V20PresExRecord,
) -> Optional[Dict[str, Any]]:
Copy link

Copilot AI Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function _presentation_request_payload is missing a docstring. Add a docstring that explains its purpose, parameters, and return value. For example: "Extract presentation request payload from a presentation exchange record, preferring by_format if available, falling back to legacy pres_request."

Suggested change
) -> Optional[Dict[str, Any]]:
) -> Optional[Dict[str, Any]]:
"""Extract presentation request payload from a presentation exchange record.
This helper prefers the `by_format.pres_request` field when available and
falls back to the legacy `pres_request` field. The legacy value may be a
plain dict or a model instance; in the latter case it is converted to a
dict representation using alias field names.
Args:
presentation: The v2.0 presentation exchange record containing the
formatted and/or legacy presentation request data.
Returns:
A dictionary representation of the presentation request payload, or
None if no request is available on the record.
"""

Copilot uses AI. Check for mistakes.
@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 6, 2026

@ff137
Copy link
Member

ff137 commented Jan 6, 2026

Re: review request, I'll be able to take a look tomorrow 👌

Copy link
Member

@ff137 ff137 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some minor suggestions before approval

@ff137
Copy link
Member

ff137 commented Jan 26, 2026

@sonivijayk please note this PR will need some finishing touches before it can be merged (mainly DCO sign offs).

@sonivijayk
Copy link
Contributor Author

@sonivijayk please note this PR will need some finishing touches before it can be merged (mainly DCO sign offs).

@ff137 Just double checked. I do not see any DCO sign off pending on the changes committed by me.

@ff137
Copy link
Member

ff137 commented Feb 3, 2026

@ff137 Just double checked. I do not see any DCO sign off pending on the changes committed by me.

Hmm... there are some merge commits maybe causing an issue. You can try a git rebase to get rid of them:

git fetch origin main
git rebase origin/main  # and resolve potential conflicts
git push --force

That should get the branch up to date and remove extra merge commits.


Edit: I see I can't do a rebase on this branch myself, because there are conflicts (but I can do a merge update). So if the conflicts are hairy (sometimes they really are, when merge commits get rebased), then the simpler way may be to create a temp branch from an up-to-date main, cherry-pick only your 4 commits that you actually want to add, and then overwrite this remote branch from that temp branch. If you want help with the git commands just let me know

@swcurran
Copy link
Contributor

@sonivijayk -- are you able to fix the DCO (DCO - Developer Certificate of Origin - https://github.com/apps/dco and https://stackoverflow.com/questions/13043357/git-sign-off-previous-commits on how to sign a previous commit) and investigate/fix the Scenario test failures? Tests are clean in other PRs, so this is likely an issue with the PR itself.

Thanks

@sonivijayk
Copy link
Contributor Author

@sonivijayk -- are you able to fix the DCO (DCO - Developer Certificate of Origin - https://github.com/apps/dco and https://stackoverflow.com/questions/13043357/git-sign-off-previous-commits on how to sign a previous commit) and investigate/fix the Scenario test failures? Tests are clean in other PRs, so this is likely an issue with the PR itself.

Thanks

Hi @swcurran I surely will take a look and fix this tonight.

@sonivijayk sonivijayk force-pushed the sonivijayk/fix/issue-3802-presentation-xchg-webhook-dedup branch from a2bf0b2 to 2d6b0f3 Compare February 18, 2026 04:19
@sonivijayk
Copy link
Contributor Author

@sonivijayk -- are you able to fix the DCO (DCO - Developer Certificate of Origin - https://github.com/apps/dco and https://stackoverflow.com/questions/13043357/git-sign-off-previous-commits on how to sign a previous commit) and investigate/fix the Scenario test failures? Tests are clean in other PRs, so this is likely an issue with the PR itself.

Thanks

Hi @swcurran

I fixed the sign-off issue on my commit(s).
The remaining DCO failures are on three existing @jamshale commits in this branch history. @jamshale can you please help review and let me know if anything required from me.

regards.

@ff137
Copy link
Member

ff137 commented Feb 18, 2026

@sonivijayk There are different options for fixing the git history


You can git rebase to try get rid of those additional merge commits:

git fetch origin main
git rebase origin/main  # and resolve potential conflicts
git push --force

They can also be dropped using interactive rebase:

git rebase -i HEAD~10
# add d in front of the merge commits to be dropped

and then rebase on main afterwards.


Alternatively, if you want to avoid resolve conflicts or interactive rebase, then:

  • make a new branch
  • cherry pick the commit hash of all the correct commits (there's 4 of them)
  • force push from the new branch to this branch
# start from clean slate off main branch
git stash
git switch main
git fetch
git pull

# create a temp branch and cherry pick relevant commits
git checkout -b temp  
git cherry-pick 8f6584b521ec459d2060d3f85f4345bead752f3c ff660b63169bfd7f42953c65c2337b75b2c1df04 b82591012c7c87e9558af9ec29b2f571cc77df32 2d6b0f3a26b72ced4aca28333487871e00c7b1dc

Then force push from that temp branch to this one (idk the command off by heart).
That'll override all the other commits


If you need help with any of the git steps, an LLM chat agent should be of assistance

@sonivijayk sonivijayk force-pushed the sonivijayk/fix/issue-3802-presentation-xchg-webhook-dedup branch from 2d6b0f3 to a8e4966 Compare February 19, 2026 04:11
Vijay Soni added 4 commits February 18, 2026 22:22
Signed-off-by: Vijay Soni <vijaysoni@sonivijay.com>
Signed-off-by: Vijay Soni <vijaysoni@sonivijay.com>
Signed-off-by: Vijay Soni <vijaysoni@sonivijay.com>
Signed-off-by: Vijay Soni <vijaysoni@sonivijay.com>
@sonivijayk sonivijayk force-pushed the sonivijayk/fix/issue-3802-presentation-xchg-webhook-dedup branch from a8e4966 to ad718db Compare February 19, 2026 04:22
Signed-off-by: Vijay Kumar Soni <vijaysoni@sonivijay.com>
@sonivijayk sonivijayk force-pushed the sonivijayk/fix/issue-3802-presentation-xchg-webhook-dedup branch from b08b342 to d3fa5a1 Compare February 19, 2026 04:54
Signed-off-by: Vijay Kumar Soni <vijaysoni@sonivijay.com>
@sonivijayk
Copy link
Contributor Author

Hi @ff137, I have fixed the commits and test failures. Please take a look.

regards

@ff137
Copy link
Member

ff137 commented Feb 19, 2026

@sonivijayk Awesome! Glad the DCO could be fixed

Please note my prior review with open comments: #3998 (review)

Signed-off-by: Vijay Kumar Soni <vijaysoni@sonivijay.com>
Vijay Kumar Soni added 6 commits February 19, 2026 23:39
Signed-off-by: Vijay Kumar Soni <vijaysoni@sonivijay.com>
Signed-off-by: Vijay Kumar Soni <vijaysoni@sonivijay.com>
Signed-off-by: Vijay Kumar Soni <vijaysoni@sonivijay.com>
Signed-off-by: Vijay Kumar Soni <vijaysoni@sonivijay.com>
Signed-off-by: Vijay Kumar Soni <vijaysoni@sonivijay.com>
Signed-off-by: Vijay Kumar Soni <vijaysoni@sonivijay.com>
@sonivijayk
Copy link
Contributor Author

@sonivijayk Awesome! Glad the DCO could be fixed

Please note my prior review with open comments: #3998 (review)

Hi @ff137 I have addressed PR comments and ran tests locally and in PR. Please review and let me know.

Thanks

Copy link
Member

@ff137 ff137 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff! Thank you for resolving all my requests and nitpicks. I'm happy to approve now

@sonarqubecloud
Copy link

@jamshale
Copy link
Contributor

There's currently a problem with the Interop tests related to the tails server used in the tests.

These tests passed before and the other tests cover this PR so I think we can go ahead and merge.

@jamshale jamshale merged commit 43cca6f into openwallet-foundation:main Feb 23, 2026
12 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants